import { EnumBetResult, EnumBjlResult } from "@/models/enums/EnumBjlResult";
import { ExcutePlan, RecmInfo, RoundInfo } from "../ExecutePlan";
import { IMoneyStrategy } from "../IMoneyStrategy";
import { IPlan } from "../IExecutePlan";
import { FixedStrategy } from "../recmStrategy/FixedStrategy";
import { BossRabbitMoneyStrategy } from "./BossRabitMoneyStrategy";
import { PlanBMoneyStrategy, PlanCMoneyStrategy } from "./WisdomMoneyStrategyV35Group";

export interface PlanAPlusOption {
    baseMoney: number;
    prevRecmMoney: number;
    stopLFailCount: number;
    failStepCount: number;
    winStepCount: number;
    stepMoney: number;
}
export class PlanAPlusMoneyStrategy implements IMoneyStrategy {

    runing: boolean = true;
    recmV: EnumBjlResult = EnumBjlResult.U;
    recmMoney: number = 0;
    prevRecmMoney: number = 0;
    baseMoney: number = 10;
    stopLFailCount: number = 3;
    recmMoneyArray: number[] = [];
    prevRecmMoneyArray: number[] = [];
    //betCountArray: number[] = [];
    // betCount: number = 0;
    winStepCount: number = -1;
    failStepCount: number = 1;
    stepMoney: number = 10;
    option: PlanAPlusOption
    constructor(name: string, option?: PlanAPlusOption) {
        this.strategyName = name;
        if (option) {
            this.option = option
        }
        else {
            this.option = {
                baseMoney: 10,
                stopLFailCount: 3,
                failStepCount: 1,
                winStepCount: -1,
                stepMoney: 10,
                prevRecmMoney: 10
            }
        }
        this.resetStrategy();
    }
    toRecmMoney(recmInfo: RecmInfo): number {
        const baseMoney = this.baseMoney;
        let recmMoney = this.recmMoney;
        let prevRecmMoney = this.prevRecmMoney;
        if (recmInfo.summaryInfo.prevResult == EnumBetResult.Success) {

            if (this.winStepCount == 0) {
                this.resetStrategy();
                recmMoney = this.recmMoney;
                prevRecmMoney = this.prevRecmMoney;

                this.recmMoney = recmMoney;
                this.prevRecmMoney = prevRecmMoney;
            }
            else if (this.winStepCount > 0) {
                for (let c = 0; c < this.winStepCount; c++) {
                    recmMoney = this.recmMoney + this.prevRecmMoney;
                    prevRecmMoney = this.recmMoney;

                    this.recmMoney = recmMoney;
                    this.prevRecmMoney = prevRecmMoney;

                    this.recmMoneyArray.push(recmMoney);
                    this.prevRecmMoneyArray.push(prevRecmMoney);
                }
            }
            else {
                let wstep = Math.abs(this.winStepCount);
                for (let c = 0; c < wstep; c++) {
                    if (this.recmMoneyArray.length > 1) {
                        this.recmMoneyArray.pop();
                        this.prevRecmMoneyArray.pop();
                        recmMoney = this.recmMoneyArray[this.recmMoneyArray.length - 1];
                        prevRecmMoney = this.prevRecmMoneyArray[this.prevRecmMoneyArray.length - 1];
                        this.recmMoney = recmMoney;
                        this.prevRecmMoney = prevRecmMoney;
                    }
                    else if (this.recmMoneyArray.length == 1) {
                        this.recmMoneyArray.pop();
                        this.prevRecmMoneyArray.pop();
                        recmMoney = baseMoney;
                        prevRecmMoney = baseMoney;
                        this.prevRecmMoney = prevRecmMoney;
                        this.recmMoney = recmMoney;
                    }
                    else {
                        recmMoney = baseMoney;
                        prevRecmMoney = prevRecmMoney;
                        this.recmMoney = recmMoney;
                        this.prevRecmMoney = prevRecmMoney;
                    }
                }
            }
        }
        else if (recmInfo.summaryInfo.prevResult == EnumBetResult.Fail) {
            if (this.failStepCount == 0) {
                this.resetStrategy();
                recmMoney = this.recmMoney;
                prevRecmMoney = this.prevRecmMoney;

                this.recmMoney = recmMoney;
                this.prevRecmMoney = prevRecmMoney;
            }
            else if (this.failStepCount > 0) {
                for (let c = 0; c < this.failStepCount; c++) {
                    recmMoney = this.recmMoney + this.prevRecmMoney;
                    prevRecmMoney = this.recmMoney;

                    this.recmMoney = recmMoney;
                    this.prevRecmMoney = prevRecmMoney;

                    this.recmMoneyArray.push(recmMoney);
                    this.prevRecmMoneyArray.push(prevRecmMoney);
                }
            }
            else {
                let fstep = Math.abs(this.failStepCount);

                for (let c = 0; c < fstep; c++) {
                    if (this.recmMoneyArray.length > 1) {
                        this.recmMoneyArray.pop();
                        this.prevRecmMoneyArray.pop();
                        recmMoney = this.recmMoneyArray[this.recmMoneyArray.length - 1];
                        prevRecmMoney = this.prevRecmMoneyArray[this.prevRecmMoneyArray.length - 1];
                        this.recmMoney = recmMoney;
                        this.prevRecmMoney = prevRecmMoney;
                    }
                    else if (this.recmMoneyArray.length == 1) {
                        this.recmMoneyArray.pop();
                        this.prevRecmMoneyArray.pop();
                        recmMoney = baseMoney;
                        prevRecmMoney = baseMoney;
                        this.prevRecmMoney = prevRecmMoney;
                        this.recmMoney = recmMoney;
                    }
                    else {
                        recmMoney = baseMoney;
                        prevRecmMoney = prevRecmMoney;
                        this.recmMoney = recmMoney;
                        this.prevRecmMoney = prevRecmMoney;
                    }
                }
            }
        }
        else { }
        return recmMoney;
    }
    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let recmV = roundInfo.userRecm;
        const originBetCount = 0;
        let recmMoney = 0;
        let prevRecmMoney = 0;

        if (recmInfo.summaryInfo.winCount >= recmInfo.summaryInfo.failCount) {
            recmMoney = this.baseMoney;
        }
        if (recmInfo.summaryInfo.winCount < recmInfo.summaryInfo.failCount) {

            //蓝色
            if (recmInfo.roundSummaryInfo.lfail >= this.stopLFailCount && this.runing) {
                this.runing = false;
                recmInfo.roundSummaryInfo.resetSummaryInfo();
                return [EnumBjlResult.U, 0];
            }
            else if (!this.runing && userRecm.summaryInfo.prevResult == EnumBetResult.Success) {
                this.runing = true;
                if (this.recmMoneyArray.length > 1) {
                    recmMoney = this.recmMoneyArray[this.recmMoneyArray.length - 2];
                    prevRecmMoney = this.prevRecmMoneyArray[this.recmMoneyArray.length - 2];
                    this.recmMoney = recmMoney;
                    this.prevRecmMoney = prevRecmMoney;
                }
                else {
                    recmMoney = this.option.baseMoney;
                    prevRecmMoney = this.option.baseMoney;
                    this.recmMoney = recmMoney;
                    this.prevRecmMoney = prevRecmMoney;
                }
                recmInfo.roundSummaryInfo.resetSummaryInfo();
                this.recmMoneyArray.push(recmMoney);
                this.prevRecmMoneyArray.push(prevRecmMoney);

                this.recmV = recmV;
                return [this.recmV, this.recmMoney];
            }
            if (!this.runing) {
                return [EnumBjlResult.U, 0];
            }
            // if (recmInfo.summaryInfo.lwin > 0 && recmInfo.summaryInfo.lwin % 2 == 0) {
            //     this.winStepCount = -2;
            // }
            // else {
            //     this.winStepCount = -1;
            // }
            recmMoney = this.toRecmMoney(recmInfo);
        }

        this.recmV = recmV;
        this.recmMoney = recmMoney;
        return [this.recmV, this.recmMoney];
    }
    showMoney(): [EnumBjlResult, number] {
        return [this.recmV, this.recmMoney];
    }
    resetStrategy(): void {
        this.runing = true;
        this.recmV = EnumBjlResult.U;
        this.recmMoney = 0;
        this.prevRecmMoney = this.option.prevRecmMoney;
        this.baseMoney = this.option.baseMoney;
        this.stopLFailCount = this.option.stopLFailCount;
        this.recmMoneyArray = [];
        this.prevRecmMoneyArray = [];
        this.winStepCount = this.option.winStepCount;
        this.failStepCount = this.option.failStepCount;
        this.stepMoney = this.option.stepMoney;
    }
    strategyName: string = "";
    debugCompoenent: string = "";
    resetRecm(): void {
        this.recmV = EnumBjlResult.U;
        this.recmMoney = 0;
    }
    copyValue(valueObj: any): void {
        let obj = valueObj as PlanAPlusMoneyStrategy;
        if (obj) {
            this.runing = obj.runing;
            this.recmV = obj.recmV;
            this.recmMoney = obj.recmMoney;
            this.prevRecmMoney = obj.prevRecmMoney;
            this.baseMoney = obj.baseMoney;
            this.stopLFailCount = obj.stopLFailCount;
            this.recmMoneyArray = obj.recmMoneyArray;
            this.prevRecmMoneyArray = obj.prevRecmMoneyArray;
            this.winStepCount = obj.winStepCount;
            this.failStepCount = obj.failStepCount;
            this.stepMoney = obj.stepMoney;
        }
    }

}
export class PlanBPlusMoneyStrategy extends PlanAPlusMoneyStrategy {
    subPlan: IPlan;
    constructor(name: string, optin: PlanAPlusOption, subPlan: IPlan) {
        super(name, optin);
        this.subPlan = subPlan;
    }
    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let recmV = roundInfo.userRecm;
        let recmMoney = 0;
        let mv = (this.subPlan.recmInfo.summaryInfo.winCount - this.subPlan.recmInfo.summaryInfo.failCount);
        if (mv >= 2) {
            recmMoney = this.toRecmMoney(recmInfo);
        }
        else if (mv >= 0 && mv < 2) {
            recmMoney = this.baseMoney;
        }
        else {
            recmV = EnumBjlResult.U;
            recmMoney = 0;
        }

        this.recmV = recmV;
        this.recmMoney = recmMoney;
        return [this.recmV, this.recmMoney];
    }
    copyValue(valueObj: any): void {
        super.copyValue(valueObj);
        let obj = valueObj as PlanBMoneyStrategy;
        if (obj) {
            this.subPlan.copyValue(valueObj.subPlan);
        }
    }
}


export class PlanCPlusMoneyStrategy extends PlanAPlusMoneyStrategy {

    subPlan: IPlan;
    constructor(name: string, optin: PlanAPlusOption, subPlan: IPlan) {
        super(name, optin);
        this.subPlan = subPlan;
    }
    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let recmV = roundInfo.userRecm;
        let recmMoney = 0;
        let mv = (this.subPlan.recmInfo.summaryInfo.winCount - this.subPlan.recmInfo.summaryInfo.failCount);
        if (mv >= 0) {
            recmMoney = this.baseMoney;
        }
        else {
            recmV = EnumBjlResult.U;
            recmMoney = 0;
        }

        this.recmV = recmV;
        this.recmMoney = recmMoney;
        return [this.recmV, this.recmMoney];
    }
}
export class WisdomMoneyStrategyV37Group implements IMoneyStrategy {
    subPlan: IPlan[];
    debugCompoenent: string = "WisdomMoneyStrategyV35GroupDebug";
    strategyName: string;
    startIndex: number = -1;
    startLevel: number = 10000;
    protected _subPlanSum: number = 0;
    public get subPlanSum() {
        return this._subPlanSum;
    }
    constructor(name?: string) {
        this.strategyName = name ?? "GroupMoneyStrategy" + (new Date()).getMilliseconds() + parseInt((Math.random() * 1000).toString());
        this.subPlan = [];
        this.resetStrategy();
    }
    showMoney(): [EnumBjlResult, number] {
        let zm = 0;
        let xm = 0;
        let recmV = EnumBjlResult.U;
        let recmMoney = 0;
        let sum = 0;


        this.subPlan.forEach(pl => {
            let [rv, rm] = pl.showMoney();
            pl.recmInfo.recmV = rv;
            pl.recmInfo.recmMoney = rm;

            if (pl.recmInfo.recmV == EnumBjlResult.Z) {
                zm += (pl.recmInfo.recmMoney * pl.multiple);

            }
            else if (pl.recmInfo.recmV == EnumBjlResult.X) {
                xm += (pl.recmInfo.recmMoney * pl.multiple);
            }
        });
        if (zm > xm) {
            recmV = EnumBjlResult.Z;
            recmMoney = zm - xm;
        }
        else if (xm > zm) {
            recmV = EnumBjlResult.X;
            recmMoney = xm - zm;
        }
        else {
            recmV = EnumBjlResult.U;
        }


        return [recmV, recmMoney];
    }
    resetRecm() {
        this.subPlan.forEach(item => item.resetRecm());
    }
    resetStrategy(): void {

        let planA = new ExcutePlan();
        planA.multiple = 1;
        planA.planName = "A计划";
        planA.recmStrategy = [new FixedStrategy({ reverse: false })];
        planA.moneyStrategy = [new PlanAPlusMoneyStrategy("A计划", {
            baseMoney: 10,
            stopLFailCount: 3,
            failStepCount: 1,
            winStepCount: -1,
            stepMoney: 10, prevRecmMoney: 10
        })];
        planA.toResult(new RoundInfo());
        this.subPlan.push(planA);

        let planB = new ExcutePlan();
        planB.multiple = 1;
        planB.planName = "B计划";
        planB.recmStrategy = [new FixedStrategy({ reverse: false })];
        planB.moneyStrategy = [new PlanBPlusMoneyStrategy("B计划", {
            baseMoney: 10,
            stopLFailCount: 3,
            failStepCount: -2,
            winStepCount: 1,
            stepMoney: 10,
            prevRecmMoney: 10
        }, planA)];
        planB.toResult(new RoundInfo());
        this.subPlan.push(planB);

        let planC = new ExcutePlan();
        planC.multiple = 1;
        planC.planName = "C计划";
        planC.recmStrategy = [new FixedStrategy({ reverse: false })];
        planC.moneyStrategy = [new PlanCPlusMoneyStrategy("C计划", {
            baseMoney: 10,
            stopLFailCount: 3,
            failStepCount: 1,
            winStepCount: -2,
            stepMoney: 10, prevRecmMoney: 10
        }, planA)];
        planC.toResult(new RoundInfo());
        this.subPlan.push(planC);

        let planD = new ExcutePlan();
        planD.multiple = 1;
        planD.planName = "D计划";
        planD.recmStrategy = [new FixedStrategy({ reverse: false })];
        planD.moneyStrategy = [new BossRabbitMoneyStrategy("D计划", {
            baseMoney: 10,
            winStep: 1,
            failStep: 0,
            prevMoney: 0,
            currentMoney: 10
        })];
        planD.toResult(new RoundInfo());
        this.subPlan.push(planD);
    }
    setSubResult(pl: ExcutePlan, roundInfo: RoundInfo) {
        pl.setResult(roundInfo, pl.recmInfo, pl.multiple, pl.waterRate, pl.fuliRate);

        let m = pl.recmInfo.summaryInfo.winMoney - pl.recmInfo.summaryInfo.failMoney;
        this._subPlanSum += m;

        let userRecmV = pl.toResult(roundInfo);
        let newRoundInfo: RoundInfo = Object.assign({}, roundInfo, { userRecm: userRecmV });
        pl.userRecmInfo.recmV = userRecmV;
        return newRoundInfo;
    }
    toSubMoney(pl: ExcutePlan, roundInfo: RoundInfo) {
        if (pl.running) {
            let [rv, rm] = pl.toMoney(roundInfo, pl.recmInfo, pl.userRecmInfo, pl.baseMoney);
            pl.recmInfo.preBetCount = pl.recmInfo.betCount;
            pl.recmInfo.recmV = rv;
            pl.recmInfo.recmMoney = rm;
            if (rv != EnumBjlResult.U) {
                //pl.recmInfo.
                pl.recmInfo.betCount++;
            }
        }
        else {
            pl.recmInfo.recmV = EnumBjlResult.U;
            pl.recmInfo.recmMoney = 0;
        }

    }
    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let recmV = EnumBjlResult.U;
        let recmMoney = 0;
        let zm = 0;
        let xm = 0;
        this.subPlan.forEach(pl => {

            let plRoundInfo = this.setSubResult(pl, roundInfo);
            this.toSubMoney(pl, plRoundInfo);

            if (pl.recmInfo.recmV == EnumBjlResult.Z) {
                zm += (pl.recmInfo.recmMoney * pl.multiple);

            }
            else if (pl.recmInfo.recmV == EnumBjlResult.X) {
                xm += (pl.recmInfo.recmMoney * pl.multiple);
            }
        })

        if (zm > xm) {
            recmV = EnumBjlResult.Z;
            recmMoney = zm - xm;
        }
        else if (xm > zm) {
            recmV = EnumBjlResult.X;
            recmMoney = xm - zm;
        }
        else {
            recmV = EnumBjlResult.U;
        }


        return [recmV, recmMoney];
    }

    copyValue(valueObj: any): void {
        var obj = valueObj as WisdomMoneyStrategyV37Group;
        if (obj) {
            this.debugCompoenent = obj.debugCompoenent;
            this.startIndex = obj.startIndex;
            this._subPlanSum = obj._subPlanSum;
            for (let i = 0; i < this.subPlan.length; i++) {
                this.subPlan[i].copyValue(obj.subPlan[i]);
            }
        }
    }
}